
const path = require('path');
const copyDir = require('recursive-copy');
const utils = require('../utils');
const del = require('del');
const codem = require('codemonster/index');

exports.javaClassPreProcess = async (ctx, task) => {
    const { pdir } = ctx;

    let bestStructure = false;
    let srcPath = undefined;
    await utils.lookUpDir(pdir, async (filename, filePath) => {
        if (srcPath) return;

        if (filename.endsWith('-persistence')) {
            let javaFolder = path.resolve(filePath, 'src/main/java');
            if (await utils.checkFileExists(javaFolder)) {
                srcPath = javaFolder;
                bestStructure = true;
            }
        } else if (filename === 'src') {
            let javaFolder = path.resolve(filePath, 'main/java');
            if (await utils.checkFileExists(javaFolder)) {
                srcPath = javaFolder;
            }
        }
    });

    srcPath = srcPath || pdir;

    let namespace = ctx['namespace'];

    if (!namespace && bestStructure) {
        //尝试解析出命名空间
        await utils.deepLookUpDir(pdir, async (filename, filePath) => {
            if (namespace) return;
    
            if (filename === 'persistence') {
                if (await utils.checkFileExists(path.resolve(filePath, 'entity')) && 
                    await utils.checkFileExists(path.resolve(filePath, 'dao'))) {
                    namespace = filePath.replace(srcPath, '').substr(1);
                    namespace = namespace.replace(path.sep + 'persistence', '');
                    namespace = namespace.replaceAll(path.sep, '.');
                }
            }
        });
    }
    
    ctx.namespace = namespace;
    ctx.srcPath = srcPath;
}

exports.javaClassGenSubTasks = (ctx, task) => {
    const prompts = [
        { type: 'Input', name: 'className', message: 'input the class name (e.g: Article): ' }
    ];
    if (ctx.namespace) {
        prompts.push({ type: 'Input', name:'namespace', message: `input the namespace (default as '${ctx.namespace}'): ` });
    } else {
        prompts.push({ type: 'Input', name:'namespace',  message: `input the namespace (e.g: com.ugeez.xxx): ` });
    }

    const subTasks = [
        { 
            task: async () => {
                ctx.inputs = await task.prompt(prompts);
            }
        }
    ];
    return subTasks;
}

exports.javaClassGenSubTasks_data2crud = (ctx, task) => {
    const prompts = [
        { type: 'Input', name: 'entityFile', message: 'input the entity file path (e.g: /Users/xxx/projects/xx/Article.java): ' }
    ];

    const subTasks = [
        { 
            task: async () => {
                ctx.inputs = ctx.inputs || {};
                const res = await task.prompt(prompts);
                if (typeof res === 'string') {
                    ctx.inputs.entityFile = res;
                } else {
                    ctx.inputs = res;
                }
            }
        }
    ];
    return subTasks;
}

exports.javaClassGenSubTasks_class2type = (ctx, task) => {
    const prompts = [
        { type: 'Input', name: 'classFile', message: 'input the java class file path (e.g: /Users/xxx/projects/xx/Article.java): ' }
    ];

    const subTasks = [
        { 
            task: async () => {
                ctx.inputs = ctx.inputs || {};
                const res = await task.prompt(prompts);
                if (typeof res === 'string') {
                    ctx.inputs.classFile = res;
                } else {
                    ctx.inputs = res;
                }
            }
        }
    ];
    return subTasks;
}

exports.javaClassGenSubTasks_api2sdk = (ctx, task) => {
    const prompts = [
        { type: 'Input', name: 'apiFile', message: 'input the java API file path (e.g: /Users/xxx/projects/xx/ArticleController.java): ' }
    ];

    const subTasks = [
        { 
            task: async () => {
                ctx.inputs = ctx.inputs || {};
                const res = await task.prompt(prompts);
                if (typeof res === 'string') {
                    ctx.inputs.apiFile = res;
                } else {
                    ctx.inputs = res;
                }
            }
        }
    ];
    return subTasks;
}

exports.tsGenSubTasks_type2crudui = (ctx, task) => {
    const prompts = [
        { type: 'Input', name: 'tsFile', message: 'input the ts file path (e.g: /Users/xxx/projects/xx/src/types.ts): ' },
        { type: 'Input', name: 'typeName', message: 'input the target Type name (e.g: Company): ' }
    ];

    const subTasks = [
        { 
            task: async () => {
                ctx.inputs = await task.prompt(prompts);
            }
        }
    ];
    return subTasks;
}

exports.javaRepoProcess = async (ctx, task) => {
    let namespace = ctx.inputs.namespace;
    if (!namespace || namespace === '') {
        namespace = ctx.namespace;
    }
    if (!namespace || namespace === '') {
        throw new Error('namespace is empty or missing');
    }
    await codem.runAsModule(ctx, [ 'java', 'repo', ctx.inputs.className, namespace ]);
}

exports.javaCRUDProcess = async (ctx, task) => {
    let namespace = ctx.inputs.namespace;
    if (!namespace || namespace === '') {
        namespace = ctx.namespace;
    }
    if (!namespace || namespace === '') {
        throw new Error('namespace is empty or missing');
    }
    await codem.runAsModule(ctx, [ 'java', 'crud', ctx.inputs.className, namespace ]);
}

exports.javaData2CRUDProcess = async (ctx, task) => {
    let entityFile = ctx.inputs.entityFile;
    if (!entityFile || entityFile === '') {
        throw new Error('entity file path is empty or missing');
    }
    await codem.runAsModule(ctx, [ 'java', 'data2crud', entityFile ]);
}

exports.javaClass2TypeProcess = async (ctx, task) => {
    let classFile = ctx.inputs.classFile;
    if (!classFile || classFile === '') {
        throw new Error('java class file path is empty or missing');
    }
    await codem.runAsModule(ctx, [ 'ts', 'class2type', classFile ]);
}

exports.javaApi2sdkProcess = async (ctx, task) => {
    let apiFile = ctx.inputs.apiFile;
    if (!apiFile || apiFile === '') {
        throw new Error('java API file path is empty or missing');
    }
    await codem.runAsModule(ctx, [ 'ts', 'api2sdk', apiFile ]);
}

exports.tsType2cruduiProcess = async (ctx, task) => {
    let { tsFile, typeName } = ctx.inputs;
    if (!tsFile || tsFile === '') {
        throw new Error('ts file path is empty or missing');
    }
    if (!typeName || typeName === '') {
        throw new Error('Type name is empty or missing');
    }
    await codem.runAsModule(ctx, [ 'react', 'cms_crud_page', typeName, tsFile ]);
}

